﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.MainTasks;
using HamcoWcs.Entitys.MesMsgQueues;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.MainTasks;
using HamcoWcs.Models.TibcoMessage;
using HamcoWcs.Models.TibcoMessage.Items;
using HamcoWcs.Service.Common;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Net;
using System.Xml;
using System.Xml.Linq;

namespace HamcoWcs.Service.Mes.Parsers
{
    /// <summary>
    /// MES 取消搬送命令
    /// </summary>
    public class PalletCancelTransportJobRequest : MesMsgParserBase
    {
        public override void HandleEvent(MesMsgQueue message)
        {
            string xml = message.Content;
            try
            {
                var jobMessage = XmlHelper.Deserialize<PalletCancelTransportJobMessage>(xml);

                var res = XmlHelper.SetReplyMessageName(xml);
                string taskId = jobMessage.Body.TRANSPORTJOBNAME;
                string unitId = jobMessage.Body.PALLETNAME;
                var mainTask = _wcsDbContext.MainTasks.Where(d => d.TaskId == taskId).Include(x => x.SubTasks).FirstOrDefault();

            
                if (mainTask == null)
                {
                    //message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                    //message.Return = res;
                    //_wcsDbContext.SaveChanges();
                    ////res = XmlHelper.SetNGReturn(res, "2", "Not find corresponding move task");
                }
                else
                {
                    switch (Enum.Parse<EnumMainTaskStatus>(mainTask.TaskStatus))
                    {
                        case EnumMainTaskStatus.NewTask:
                        case EnumMainTaskStatus.Ready:
                            mainTask.TaskStatus = EnumMainTaskStatus.Cancel.ToString();
                            break;
                        case EnumMainTaskStatus.OnProgress:
                            res = XmlHelper.SetNGReturn(res, "3", "Cannot cancel a started task");
                            break;
                        case EnumMainTaskStatus.Finished:
                            res = XmlHelper.SetNGReturn(res, "4", "Task is finished");
                            break;
                        case EnumMainTaskStatus.Error:
                            res = XmlHelper.SetNGReturn(res, "5", "Task is error");
                            break;
                        case EnumMainTaskStatus.Delete:
                        case EnumMainTaskStatus.Cancel:
                        default:
                            res = XmlHelper.SetNGReturn(res, "6", "Task is deleted or cancel");
                            break;
                    }
                }

                var doc = new XmlDocument();
                doc.LoadXml(res);

                var node = doc.SelectSingleNode("//BODY");
                var address = _locationService.GetAddress(unitId);

                SetNewNode(doc, node, "CURRENTMACHINENAME", address.MachineName);
                SetNewNode(doc, node, "CURRENTPOSITIONTYPE", address.PositionType);
                SetNewNode(doc, node, "CURRENTPOSITIONNAME", address.PositionName);
                SetNewNode(doc, node, "CURRENTZONENAME", address.ZoneName);

                //message.Return = res;
                message.Return = XmlHelper.XmlDocumentToString(doc);
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                _wcsDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                var res = XmlHelper.SetReplyMessageName(xml);
                message.Return = XmlHelper.SetNGReturn(res, "7", "Unkonw exception");
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                AddSystemErrorLog(xml, ex);
            }
        }


        private void SetNewNode(XmlDocument doc, XmlNode node, string subNodeName, string value)
        {
            var sNode = node.SelectSingleNode($"//{subNodeName}");
            if (sNode is null)
            {
                sNode = doc.CreateElement(subNodeName);
                node.AppendChild(sNode);
            }

            sNode.InnerText = value;
        }

        private readonly ILocationService _locationService;
        public PalletCancelTransportJobRequest(ILocationService locationService, ILoggerService loggerService, WcsDbContext wcsDbContext, IMapper mapper)
            : base(loggerService, wcsDbContext, mapper)
        {
            _locationService = locationService;
        }

        public override string EventName => "PALLETCANCELTRANSPORTJOBREQUEST";

    }
}
